package com.yesun.task.pipeline;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.mchange.io.FileUtils;
import com.yesun.task.pipeline.common.Config;
import com.yesun.task.pipeline.common.Constant;
import com.yesun.task.pipeline.common.JobUtil;
import com.yesun.task.pipeline.domain.dto.JobDto;
import com.yesun.task.pipeline.quartz.JobSchedule;
import com.yesun.task.pipeline.quartz.QuartzJob;
import com.yesun.task.pipeline.sink.ClickhouseSink;
import com.yesun.task.pipeline.worker.ParallelWorker;
import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.annotation.MapperScan;
import org.quartz.SchedulerException;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.actuate.autoconfigure.endpoint.web.CorsEndpointProperties;
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties;
import org.springframework.boot.actuate.autoconfigure.web.server.ConditionalOnManagementPort;
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementPortType;
import org.springframework.boot.actuate.endpoint.ExposableEndpoint;
import org.springframework.boot.actuate.endpoint.web.*;
import org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpointsSupplier;
import org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpointsSupplier;
import org.springframework.boot.actuate.endpoint.web.servlet.WebMvcEndpointHandlerMapping;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.core.env.Environment;

import javax.annotation.PostConstruct;
import java.util.*;

@Slf4j
@SpringBootApplication
@EnableConfigurationProperties({Config.class})
@MapperScan(basePackages = "com.yesun.task.pipeline.mapper")
public class TaskPipelineApplication implements ApplicationRunner {

    @Value("${task-pipeline.basePath}")
    private String basePath;
    @Value("${task-pipeline.conf}")
    private String conf;

    public static void main(String[] args) {
        log.debug("SpiderPipeline starting...");
        SpringApplication.run(TaskPipelineApplication.class, args);
        log.debug("SpiderPipeline started!");

        //启动Worker，需要bean都实例化完成
        log.info("Start BatchInsertWorker...");
        ClickhouseSink.BatchInsertWorker batchInsertWorker = new ClickhouseSink.BatchInsertWorker();
        batchInsertWorker.setName("BatchInsertWorker");
        batchInsertWorker.start();

        log.info("Start BatchInsertNewsWorker...");
        ClickhouseSink.BatchInsertNewsWorker batchInsertNewsWorker = new ClickhouseSink.BatchInsertNewsWorker();
        batchInsertNewsWorker.setName("BatchInsertNewsWorker");
        batchInsertNewsWorker.start();

    }

    @PostConstruct //这不是springboot的注解
    public void init() {
        //启动Worker
        log.info("init()...");
    }

    @Bean
    @ConditionalOnManagementPort(ManagementPortType.SAME)
    public WebMvcEndpointHandlerMapping webEndpointServletHandlerMapping(WebEndpointsSupplier webEndpointsSupplier, ServletEndpointsSupplier servletEndpointsSupplier, ControllerEndpointsSupplier controllerEndpointsSupplier, EndpointMediaTypes endpointMediaTypes, CorsEndpointProperties corsProperties, WebEndpointProperties webEndpointProperties, Environment environment) {
        List<ExposableEndpoint<?>> allEndpoints = new ArrayList<>();
        Collection<ExposableWebEndpoint> webEndpoints = webEndpointsSupplier.getEndpoints();
        allEndpoints.addAll(webEndpoints);
        allEndpoints.addAll(servletEndpointsSupplier.getEndpoints());
        allEndpoints.addAll(controllerEndpointsSupplier.getEndpoints());
        String basePath = webEndpointProperties.getBasePath();
        EndpointMapping endpointMapping = new EndpointMapping(basePath);
        boolean shouldRegisterLinksMapping = webEndpointProperties.getDiscovery().isEnabled() &&
                (org.springframework.util.StringUtils.hasText(basePath) || ManagementPortType.get(environment).equals(ManagementPortType.DIFFERENT));
        return new WebMvcEndpointHandlerMapping(endpointMapping, webEndpoints, endpointMediaTypes, corsProperties.toCorsConfiguration(), new EndpointLinksResolver(allEndpoints, basePath), shouldRegisterLinksMapping, null);
    }

    //SpringBoot启动后，启动Worker
    @Override
    public void run(ApplicationArguments args) throws Exception {
        //启动Worker
        log.info("Start ParallelWorker...");
        ParallelWorker worker = new ParallelWorker(4);
        worker.startWorkers();
        //从配置文件加载JOB
        JobUtil.initJobFromConf(basePath, conf);
    }
}
